// -----------------------------------------------------------------------
// <copyright file="Program.cs" company="Asynkron AB">
//      Copyright (C) 2015-2024 Asynkron AB All rights reserved
// </copyright>
// -----------------------------------------------------------------------

using System;
using System.Threading.Tasks;
using chat.messages;
using Microsoft.Extensions.Logging;
using Proto;
using Proto.Remote;
using Proto.Remote.GrpcNet;
using static Proto.Remote.RemoteConfig;

Log.SetLoggerFactory(LoggerFactory.Create(c => c
    .SetMinimumLevel(LogLevel.Information)
    .AddConsole()
));

var config =
    BindToLocalhost()
        .WithProtoMessages(ChatReflection.Descriptor);

var system = new ActorSystem().WithClientRemote(config);
await system.Remote().StartAsync();

var context = system.Root;

var client = context.Spawn(
    Props.FromFunc(
        ctx =>
        {
            switch (ctx.Message)
            {
                case Connected connected:
                    Console.WriteLine(connected.Message);
                    break;
                case SayResponse sayResponse:
                    Console.WriteLine($"{sayResponse.UserName} {sayResponse.Message}");
                    break;
                case NickResponse nickResponse:
                    Console.WriteLine($"{nickResponse.OldUserName} is now {nickResponse.NewUserName}");
                    break;
            }

            return Task.CompletedTask;
        }
    )
);

var server = PID.FromAddress("127.0.0.1:8000", "chatserver");

context.Send(
    server,
    new Connect
    {
        Sender = client
    }
);

var nick = "Alex";

while (true)
{
    var text = Console.ReadLine();

    if (string.IsNullOrWhiteSpace(text))
    {
        continue;
    }

    if (text.Equals("/exit"))
    {
        break;
    }

    if (text.StartsWith("/nick "))
    {
        var t = text.Split(' ')[1];

        context.Send(
            server,
            new NickRequest
            {
                OldUserName = nick,
                NewUserName = t
            }
        );

        nick = t;

        continue;
    }

    context.Send(
        server,
        new SayRequest
        {
            UserName = nick,
            Message = text
        }
    );
}

await system.Remote().ShutdownAsync();
